package com.ksyun.campus.client.util;


import cn.hutool.json.JSONUtil;
import okhttp3.*;
import okio.BufferedSink;

import java.io.IOException;
import java.io.OutputStream;
import java.net.ConnectException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * minFs 系统 对 okhttp的封装
 */
public class FSHttpUtils {

    private static final OkHttpClient okHttpClient = new OkHttpClient();
    private static final Request.Builder httpBuilder = new Request.Builder();

    private static final String HTTP_PREFIX = "http://";

    public static HttpResult write(String url, byte[] bytes, String path, String headFileSystem, int offset, int len) {
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"),bytes);
        Request request = httpBuilder
                .url(String.format("%s?path=%s&offset=%s&length=%s", HTTP_PREFIX + url, path, offset, len))
                .post(requestBody)
                .removeHeader("fileSystem")
                .header("fileSystem", headFileSystem)
                .build();
        Response response = null;
        HttpResult result = null;
        try {
            response = okHttpClient.newCall(request).execute();
            result = new HttpResult(response.code(), response.headers().toMultimap(), response.body().string());
        }catch (ConnectException e){
            return null;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return result;
    }

    public static byte[] read(String url, String path, String headFileSystem, int offset, int len) {
        Request request = httpBuilder.url(String.format("%s?path=%s&offset=%s&length=%s", HTTP_PREFIX + url, path, offset, len))
                .get()
                .removeHeader("fileSystem")
                .header("fileSystem", headFileSystem)
                .build();
        Response response = null;
        try {
            response = okHttpClient.newCall(request).execute();
            if(!response.isSuccessful()){
                return new byte[0];
            }
            return response.body().bytes();
        }catch (ConnectException e){
            return new byte[0];
        }
        catch (IOException e) {
            e.printStackTrace();
            return new byte[0];
        } finally {
            if (response != null) {
                response.close();
            }
        }
    }


    public static HttpResult post(String url, Map<String, String> param, String headFileSystem, Object o) {
        String paramStr = convertString(param);
        url = url + (paramStr == null ? "" : "?" + paramStr);
        String jsonStr = JSONUtil.parseObj(o).toString();
        RequestBody  requestBody = RequestBody.create(MediaType.parse("application/json"), jsonStr);
        Request request = httpBuilder.url(HTTP_PREFIX + url)
                .post(requestBody)
                .removeHeader("fileSystem")
                .header("fileSystem", headFileSystem)
                .build();
        Response response = null;
        HttpResult result = null;
        try {
            response = okHttpClient.newCall(request).execute();
            result = new HttpResult(response.code(), response.headers().toMultimap(), response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return result;
    }


    public static HttpResult get(String url, String path, String headFileSystem) {
        Request request = httpBuilder.url(String.format("%s?path=%s", HTTP_PREFIX + url, path))
                .get()
                .removeHeader("fileSystem")
                .header("fileSystem", headFileSystem)
                .build();
        Response response = null;
        HttpResult result = null;
        try {
            response = okHttpClient.newCall(request).execute();
            result = new HttpResult(response.code(), response.headers().toMultimap(), response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return result;
    }


    public static HttpResult get(String url, Map<String, String> param, String headFileSystem) {
        String paramStr = convertString(param);
        url = url + (paramStr == null ? "" : "?" + paramStr);
        Request request = httpBuilder.url(HTTP_PREFIX + url)
                .get()
                .removeHeader("fileSystem")
                .header("fileSystem", headFileSystem)
                .build();
        Response response = null;
        HttpResult result = null;
        try {
            response = okHttpClient.newCall(request).execute();
            result = new HttpResult(response.code(), response.headers().toMultimap(), response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return result;
    }


    public static class HttpResult {
        public final int code;
        public final Map<String, List<String>> headers;
        public final String content;

        public HttpResult(int code, String content) {
            this.code = code;
            this.headers = null;
            this.content = content;
        }

        public HttpResult(int code, Map<String, List<String>> headers, String content) {
            this.code = code;
            this.headers = headers;
            this.content = content;
        }
    }

    private static String convertString(Map<String, String> param) {
        StringBuilder sb = new StringBuilder();
        if (null == param) {
            return null;
        } else {
            Iterator<Map.Entry<String, String>> iter = param.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<String, String> next = iter.next();
                sb.append(next.getKey()).append("=");
                sb.append(next.getValue());
                if (iter.hasNext()) {
                    sb.append("&");
                }
            }
            return sb.toString();
        }
    }

}
